R para Análise de Dados

Bruno Crotman

17/08/2019

INTRODUÇÃO

Objetivos do curso

Meta final: que vários dos processos de análise de dados da empresa passem a ser feitos dentro do fluxo de trabalho do R.

Ao fim do curso o objetivo é que todos os fios da meada sejam puxados para que o aluno consiga continuar por si só usando a vasta documentação disponível.

Por que programar?

Também amo o Excel, mas amo mais as seguintes vantagens:

Por que programar em R?

Fluxo de trabalho

Pequeno exemplo para motivação

É muito comum possuirmos dados gerados em planilhas ou em algum suporte de formarto estruturado.

Neste exemplo, temos planilhas deste formato formato especificado

Demo Planel

Ambiente R/RStudio

R é uma linguagem que é interpretada por um engine gratuito.

RStudio é o melhor ambiente de programação da linguagem R. A versão mais simples, que é totalmente funcional, é gratuita.

Na visualização padrão, ele oferece um console para execução de comandos e uma janela com a visualização dos environments, ou seja, das variáveis que ele guarda na sessão atual.

RStudio como console

No console é possível executar comandos, como o que atribui valor a uma variável

x <- 1

Note que a atribuição é feita com <- e não com = como na maioria das linguagens.

Dica: o atalho alt + - gera o sinal de atribuição

Os comandos que não atribuem valor a uma variável são ecoados na tela

x + 2
## [1] 3

Veja o [1] no console. O R considera que tudo é um vetor. É uma linguagem muito baseada em operações vetoriais. Isso facilita muito as coisas quando se lida com dados.

RStudio como IDE para um script

O console serve só para testes, aprendizado de novos comandos, debug, experiências etc.

Para as atividades mais comuns de análise de dados, e para que elas sejam reprodutíveis, é necessária a criação de scripts.

Eles são salvos em um arquivo de extensão “.r”

Funcionalidades interessantes do RStudio

Baixando o material do github

Todo o material do curso está hospedado no Github, inclusive esta apresentação, escrita em RMarkdown.

Os exemplos de código, as imagens e os dados mostrados nesta apresentação estão inclusos no repositório do curso.

O repositório fica em github/crotman/cursoR.

Para baixar este repositório no RStudio, crie um projeto em File/New Project, do tipo Github e use o endereço do repositório: https://github.com/crotman/CursoR.git.

Todo material é disponibilizado sob a licença Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License

FUNDAMENTOS DA LINGUAGEM

Tipos de valores “armazenados” por variáveis

Para o R, simplificando para o escopo deste curso, as variáveis “armazenam” os seguintes tipos:

1L:10L
##  [1]  1  2  3  4  5  6  7  8  9 10
list("oi", 1L)
## [[1]]
## [1] "oi"
## 
## [[2]]
## [1] 1
tibble(col1 = 1:10, col2 = 11:20 )
## # A tibble: 10 x 2
##     col1  col2
##    <int> <int>
##  1     1    11
##  2     2    12
##  3     3    13
##  4     4    14
##  5     5    15
##  6     6    16
##  7     7    17
##  8     8    18
##  9     9    19
## 10    10    20

Tipos de valores “armazenados” por variáveis (cont.)

f <- function(a, b){
    a + b
}

g <- f

g(1L, 2L)
## [1] 3
e1 <- rlang::env(
    a = 1L,
    b = "sou o b",
    c = 1L:20L
)

get("b", e1)
## [1] "sou o b"

Tipos de valores “armazenados” por variáveis (cont.)

Existe orientação a objetos no R, mas não está no escopo deste curso

Note que não há variáveis que armazenam dado escalar, como já vimos.

Dentre os vetores há:

Tipos de vetores

Fonte: Advanced R

Tipos de valores “armazenados” por variáveis (cont.)

Os vetores atômicos podem ser dos seguintes tipos:

Tipos primários

Fonte: Advanced R

Tipos de vetores atômicos

booleano <- !TRUE 

booleano
## [1] FALSE
inteiro <- 8L 

typeof(inteiro + 1L)
## [1] "integer"
typeof(inteiro + 1)
## [1] "double"

Tipos de vetores atômicos (cont.)

double <- 0.1

double_cientifico <- 1.5e3

infinito <- Inf 
double
## [1] 0.1
double_cientifico
## [1] 1500
infinito
## [1] Inf

Cobinando vetores em vetores maiores usando c()

Uma das funções mais usadas do R é c(), que cria um vetor novo vetor combinando vetores.

c(1, 2, 3)
## [1] 1 2 3
c(1, 2, 3, c(4, 5, 6))
## [1] 1 2 3 4 5 6
1.4 : 9.4
## [1] 1.4 2.4 3.4 4.4 5.4 6.4 7.4 8.4 9.4

Outras formas de gerar um vetor

O operador : é usado para gerar um vetor com todos números que estão entre os operandos e são formados somando números inteiros ao primeiro operando.

1L:10L
##  [1]  1  2  3  4  5  6  7  8  9 10
1.5:9.1
## [1] 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5

A função seq() é usada para criar um vetor de várias formas.

Numa das formas especifica-se o valor inicial, o valor final e o incremento entre elementos do vetor.

seq(1, 9.99, 0.1)
##  [1] 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6
## [18] 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 4.0 4.1 4.2 4.3
## [35] 4.4 4.5 4.6 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0
## [52] 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.0 7.1 7.2 7.3 7.4 7.5 7.6 7.7
## [69] 7.8 7.9 8.0 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9 9.0 9.1 9.2 9.3 9.4
## [86] 9.5 9.6 9.7 9.8 9.9

Parâmetros nomeados

Note que chamamos a função passando os parâmetros sem especificação de quais são eles. Eles são recebidos pela função dem específica.

Mas no R também é possível passar parâmetros de forma nomeada.

Clique em F1 enquanto tem o cursor em cima da função e veja a ordem dos parâmetros. Veja que outros parâmetros que não utilizamos. Podemos usar length.out ao invés de by:

seq(1L, 10L, length.out = 10L)
##  [1]  1  2  3  4  5  6  7  8  9 10
seq(1L, 10L, length.out = 5L)
## [1]  1.00  3.25  5.50  7.75 10.00

Outro parâmetro, along.with, deixa que criemos um vetor num intervalo determinado e o mesmo número de elementos do vetor passado por este parâmetro.

seq(20, 100, along.with = 1:10)
##  [1]  20.00000  28.88889  37.77778  46.66667  55.55556  64.44444  73.33333
##  [8]  82.22222  91.11111 100.00000

Valores faltantes NA

Valores faltantes ou desconecidos são representados por NA

a <- c(1L,NA)
a
## [1]  1 NA

O valor NA quase sempre contamina os cálculos

media <- mean(a)
media
## [1] NA

mas…

media <- mean(a, na.rm = TRUE)
media
## [1] 1

A exceção são expressões que dão sempre o mesmo resultado independentemente do valor da variável

NA ^ 0
## [1] 1
NA | TRUE
## [1] TRUE
NA & FALSE
## [1] FALSE

A melhor forma de testar se existe um valor NA é is.na

v <- c(1, NA, 2)

is.na(v)
## [1] FALSE  TRUE FALSE

Programação com vetores

As operações do R são vetoriais. Numa operação entre um vetor e um escalar, a operação com o escalar é aplicada a cada elemento do vetor

1:5 * 2
## [1]  2  4  6  8 10
1:10 / 10
##  [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Numa operação com vetores do mesmo tamanho, os elementos são pareados

1:10 * 1:10
##  [1]   1   4   9  16  25  36  49  64  81 100

Programação com vetores - recycling

Outro conceito importante é o de recycling.

Numa operação entre dois vetores de tamanhos diferentes, o vetor menor é repetido ciclicamente de forma a ficar com o mesmo tamanho do vetor maior.

Lembra que toda variável no R é um vetor?

Então… o escalar mostrado no primeiro código do slide anterior é um vetor de 1 elemento que sofre recycling

1:10 * 1:2
##  [1]  1  4  3  8  5 12  7 16  9 20

Estruturas construídas a partir de vetores e listas

Existem estruturas mais complexas na linguagem construídas a partir de vetores e listas.

Vamos passar pelo Data Frame agora. Depois por Factor e objetos que representam Datas

Data Frames

Data Frames, e seu primo Tibble, são estruturas muito usadas em análises de dados feitas em R.

O dataframe consiste em um conjunto de vetores nomeados, com o mesmo número de elementos, que formam uma estrutura retangular, onde cada coluna é um vetor e cada linha n contém o n-ésimo elemento dos vetores.

É similar, em muitas características, a uma tabela de banco de dados.

Essa estrutura é chave no paradigma “Tidy” que usaremos com as bibliotecas Tidyverse

Tibble é uma adaptação do Data Frame para análise de dados. Discutir essas diferenças está fora do escopo do curso. Algumas diferenças serão citadas o longo do material e justificam o uso do Tibble.

df <- 
    data.frame(
        nome = c("João", "Maria", "Zezinho", "Juquinha"), 
        idade = c(7, 8, 9, 10), 
        altura = c(10, 11)
    )
df
##       nome idade altura
## 1     João     7     10
## 2    Maria     8     11
## 3  Zezinho     9     10
## 4 Juquinha    10     11
#tibble não aceita recycling em vetores de tamanho diferente de 1
tib <- 
    #try evita que o erro paralise toda a execução do script
    try(
        tibble(
            nome = c("João", "Maria", "Zezinho", "Juquinha"), 
            idade = c(7, 8, 9, 10), 
            altura = c(10, 11)
        )
    )
## Error : Tibble columns must have consistent lengths, only values of length one are recycled:
## * Length 2: Column `altura`
## * Length 4: Columns `nome`, `idade`
## Backtrace:
##      x
##   1. +-rmarkdown::render("D:/DataQuant/CursoR/Conteudo.Rmd", encoding = "UTF-8")
##   2. | \-knitr::knit(...)
##   3. |   \-knitr:::process_file(text, output)
##   4. |     +-base::withCallingHandlers(...)
##   5. |     +-knitr:::process_group(group)
##   6. |     \-knitr:::process_group.block(group)
##   7. |       \-knitr:::call_block(x)
##   8. |         \-knitr:::block_exec(params)
##   9. |           +-knitr:::in_dir(...)
##  10. |           \-knitr:::evaluate(...)
##  11. |             \-evaluate::evaluate(...)
##  12. |               \-evaluate:::evaluate_call(...)
##  13. |                 +-evaluate:::timing_fn(...)
##  14. |                 +-base:::handle(...)
##  15. |                 +-base::withCallingHandlers(...)
##  16. |                 +-base::withVisible(eval(expr, envir, enclos))
##  17. |                 \-base::eval(expr, envir, enclos)
##  18. |                   \-base::eval(expr, envir, enclos)
##  19. +-base::try(...)
##  20. | \-base::tryCatch(...)
##  21. |   \-base:::tryCatchList(expr, classes, parentenv, handlers)
##  22. |     \-base:::tryCatchOne(expr, names, parentenv, handlers[[1L]])
##  23. |       \-base:::doTryCatch(return(expr), name, parentenv, handler)
##  24. \-tibble::tibble(...)
##  25.   \-tibble:::lst_to_tibble(xlq$output, .rows, .name_repair, lengths = xlq$lengths)
##  26.     \-tibble:::recycle_columns(x, .rows, lengths)

Controle de fluxo

A linguagem oferece comandos de controle de fluxo similares aos de outras linguagens.

Podemos dividir os comandos de controle de fluxo em dois tipos:

Choices: if, ifelse

O comando if funciona para um valor lógico escalar

if (2 + 2 == 4) {
    "2 mais 2 são 4"
} else {
    "2 mais 2 não são 4"
}
## [1] "2 mais 2 são 4"

Note o operador de comparação == e não =

A função if_else (da biblioteca dplyr) funciona de vetorial. if_else é mais rápida que a função ifelse da biblioteca base, mas só aceita argumentos de mesmo tipo no segundo e terceiro parâmetros

jogo_do_pim_silvio_santos <- if_else(
    condition = 1:40 %% 4 == 0 ,
    true =  "PIM",
    false =  as.character(1:40)
)
jogo_do_pim_silvio_santos
##  [1] "1"   "2"   "3"   "PIM" "5"   "6"   "7"   "PIM" "9"   "10"  "11" 
## [12] "PIM" "13"  "14"  "15"  "PIM" "17"  "18"  "19"  "PIM" "21"  "22" 
## [23] "23"  "PIM" "25"  "26"  "27"  "PIM" "29"  "30"  "31"  "PIM" "33" 
## [34] "34"  "35"  "PIM" "37"  "38"  "39"  "PIM"

Note o operador %% e a função de coerção de tipo as.character

Choices: switch e case_when

A cláusula switch e a função dplyr::case_when evitam que o programador tenha que criar muitos if else aninhados

letra <- "b"

switch(
    letra,
    "a" = "começa com a",
    "b" = "começa com b",
    stop("deu ruim")
)
## [1] "começa com b"

Note que a condição vai sendo testada na ordem e stop gera um erro

case_when serve ao caso vetorial

case_when(
    1:40 %% 10 == 0 ~ "dezena",
    1:40 %% 2 == 0 ~ "par",
    TRUE ~ as.character(1:40)
)
##  [1] "1"      "par"    "3"      "par"    "5"      "par"    "7"     
##  [8] "par"    "9"      "dezena" "11"     "par"    "13"     "par"   
## [15] "15"     "par"    "17"     "par"    "19"     "dezena" "21"    
## [22] "par"    "23"     "par"    "25"     "par"    "27"     "par"   
## [29] "29"     "dezena" "31"     "par"    "33"     "par"    "35"    
## [36] "par"    "37"     "par"    "39"     "dezena"

Loops

A cláusula de loop mais usada e mais versátil é for

for(i in 1:5){ 
    print(i^2)
}
## [1] 1
## [1] 4
## [1] 9
## [1] 16
## [1] 25

As cláusulas next e break modificam o comportamento, respectivamente caminhando direto para a próxima iteração e saindo do for

#next vai pra próxima iteração
for(i in 1:5){
    if (i %% 2 == 0){
        next
    }
    print(i)
}
## [1] 1
## [1] 3
## [1] 5
#next sai do loop
for(i in 1:5){
    if (i %% 2 == 0){
        break
    }
    print(i)
}
## [1] 1

Loops: coisa do passado

Vamos ver que quase sempre é desnecessário usar loop para as tarefas que vamos executar.

O caráter vetorial da linguagem, aliado a funcionalidades das bibliotecas, faz com que a grande maioria dos loops sejam desnecessários.

O código fica mais limpo e expressivo e mais rápido. Às vezes MUITO mais rápido. Isso ocorre por motivos além do escopo do curso (alocação de memória, código interpretado x código compilado em C++ etc.)

O código abaixo usa loop e programação funcional, respectivamente. Programação funcional será abordada posteriormente no material.

com_loop <- function(n){
    x <- integer()
    for (i in 1:n){
        x <- c(x, i^2)
    }
    x
}

#programação funcional: aprenderemos posteriomente
sem_loop <- function(n){
    x <- 1:n %>% 
        map_dbl(function(x){x^2})
    x
}

Abaixo as três formas de fazer a mesma conta que terão a performance avaliada

com_loop(5)
## [1]  1  4  9 16 25
sem_loop(5)
## [1]  1  4  9 16 25
(1:5)^2
## [1]  1  4  9 16 25

Loops: coisa do passado (cont.)

A biblioteca bench oferece funções ótimas para avaliar a performance de pedaços pequenos de código.

resultados_perf <- mark(
    sem_loop(1e4),
    com_loop(1e4),
    (1:1e4)^2
)

#aprenderemos o que é %>% e select() posteriormente 
resultados_perf %>% 
    select(expression, min, median, `itr/sec` )
## # A tibble: 3 x 4
##   expression           min   median `itr/sec`
##   <bch:expr>      <bch:tm> <bch:tm>     <dbl>
## 1 sem_loop(10000)   6.22ms   6.69ms    143.  
## 2 com_loop(10000)  88.06ms  93.71ms      9.61
## 3 (1:10000)^2       15.8us     17us  44851.
plot(resultados_perf)

Exemplo de simulação: Monty Hall

Monty Hall era uma espécie de Sílvio Santos juvenil (sub 80) americano.

Um dos seus jogos consistia em mostrar três portas ao otár… (ops) convidado. Em uma delas tem um carro.

Antes do resultado, o apresentador revela uma das portas e pergunta se o convidado que trocar a escolha.

O que vocês acham? Melhor trocar, manter a escolha original ou tanto faz?

Simulando o Monty Hall

Note o que há de interessante no código (comentado)

set.seed(88)

joga_monty_hall <- function(troca){
    portas <- 1:3
    #sample() sorteia elementos com ou sem reposição
    porta_carro <- sample(portas, size = 1, replace = FALSE)
    primeira_escolha <- 1
    #Seleção negativa (retirando elementos)
    portas_pra_revelar <- portas[-c(porta_carro, primeira_escolha)]
    porta_revelada <- sample( c(portas_pra_revelar, portas_pra_revelar  ), 1)

    if(troca){
        escolha <- portas[-c(primeira_escolha, porta_revelada)]
    }
    else{
        escolha <- primeira_escolha
    }
    
    escolha == porta_carro
        
}

n <- 1000
#replicate executa múltiplas vezes um comando e armazena os resultados em uma estruturaúnica
troca <- replicate(n = n, joga_monty_hall(troca = TRUE))
fica  <- replicate(n = n, joga_monty_hall(troca = FALSE))

Resultados:

sum(troca)/n
## [1] 0.675
sum(fica)/n
## [1] 0.323

Outra simulação: dá pra passar no CFA sem saber nada?

Vamos ver… mas dá pra simular sem saber quase nada.

Vamos usar uma das funções da família r<familia de distribuição de prob>(). Neste caso, a rbinom, que simula a distribução binomial (aquela que equivale ao evento de jogar n moedas (ou alguma coisa com dois lados) para cima e ver quantas deram cara).

n_simul <- 10000
n_questoes <- 240
min_aprovacao <-  0.6
n_aprovado <- 240 * min_aprovacao
prob_questao <- 0.2

acertos <- rbinom(n = n_simul, size = n_questoes, prob = prob_questao   )

sum(acertos >= n_aprovado)/n_simul 
## [1] 0

A chance é praticamente nula.

Na verdade, a grande massa da distribuição fica muito distante.

dado <- enframe(acertos/n_questoes)

mostra_chances <- function(acertos, n_questoes){
    ggplot(enframe(acertos/n_questoes)) +
        geom_density( aes(x = value)) +
        scale_x_continuous(
            labels = percent_format(accuracy = 1), 
            limits = c(0,1),
            breaks = seq(0, 1, 0.1) 
            ) +
        labs(x ="% Acertos") +
        geom_vline(xintercept = min_aprovacao, color = "red") +
        theme_light()
}

mostra_chances(acertos, n_questoes)

Outra simulação: dá pra passar no CFA sabendo a um grau x ?

O exemplo anterior era muito simplista: ninguém chuta tudo.

Imagine que sabemos qual a chance de aparecer uma pergunta onde podemos descartar 0 alternativas, a chance de uma onde descartamos 1 e assim por diante.

#definindo a chance podermos eliminar 0, 1, 2, ... 4 alternativas
fracao_eliminar_questoes <- c( 0.1, 0.1, 0.2, 0.25 , 0.35 ) 
#definindo o número de questões 
n_questoes_cada_elimina <- t(rmultinom(n_simul, size = n_questoes, fracao_eliminar_questoes))
probs_quando_elimina <- 1/(5:1)
acertos_concatenados <- 
    rbinom( 
        n =  n_simul * 5 , 
        size = as.vector(t(n_questoes_cada_elimina)), 
        prob = probs_quando_elimina  
    )
n_questoes_cada_elimina[1:4,]
##      [,1] [,2] [,3] [,4] [,5]
## [1,]   23   24   50   47   96
## [2,]   24   17   48   64   87
## [3,]   23   30   43   56   88
## [4,]   20   25   51   52   92
acertos_concatenados[1:20]
##  [1]  4  6 17 25 96  4  3 13 34 87  6  5 13 36 88  4  9 17 25 92
matriz_acertos <- matrix(acertos_concatenados, byrow = TRUE, nrow = n_simul )

matriz_acertos[1:5,]
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    4    6   17   25   96
## [2,]    4    3   13   34   87
## [3,]    6    5   13   36   88
## [4,]    4    9   17   25   92
## [5,]    6    5   11   30   92
acertos <- rowSums(matriz_acertos)
sum(acertos > n_aprovado)/n_simul
## [1] 0.3131
mostra_chances(acertos, n_questoes)

Exemplo inicial de visualização de dados

library(ggplot2)

ggplot(data = mpg) + 
    geom_point(mapping = aes(x = displ, y = hwy))

TIDY DATA (obtenção e organização dos dados)

Organizando os dados de forma tidy

Arrumar os dados de forma que as linhas sejam eventos e as colunas sejam atributos do evento ajuda muito a rodar modelos e construir visualizações eficientemente.

O que é o evento e o que é o atributo pode variar até para diferentes usos do mesmo dado. Mas a prática ajuda a determinar isso.

Tratamento de dados em passos: operador Pipe (%>%)

Normalmente os tratamentos de dados são feitos em múltiplos passos encadeados:

#dados de exemplo
head(gapminder)
## # A tibble: 6 x 6
##   country     continent  year lifeExp      pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Afghanistan Asia       1952    28.8  8425333      779.
## 2 Afghanistan Asia       1957    30.3  9240934      821.
## 3 Afghanistan Asia       1962    32.0 10267083      853.
## 4 Afghanistan Asia       1967    34.0 11537966      836.
## 5 Afghanistan Asia       1972    36.1 13079460      740.
## 6 Afghanistan Asia       1977    38.4 14880372      786.

Vamos imaginar que queremos a média de PIB per capita por continente em 2007.

Note quanto código desnecessário há nestas linhas: variáveis que não precisavam ser nomeadas nem passadas explicitamente como parâmetro.

Este código desnecessário causa fadiga no programador e confunde o próprio programador e o leitor posterior do código.

#vamos cobrir essas funções de tratamento posteriormente
gapminder_07 <- filter(gapminder, year == 2007)
gapminder_07_group_continente <- group_by(gapminder_07, continent)
gapminder_media_gdp_continente <- summarise(
    gapminder_07_group_continente, media_gdp = sum(gdpPercap * pop)/sum(pop)
)
resultado <- arrange(gapminder_media_gdp_continente, desc(media_gdp))

resultado
## # A tibble: 5 x 2
##   continent media_gdp
##   <fct>         <dbl>
## 1 Oceania      32885.
## 2 Europe       25244.
## 3 Americas     21603.
## 4 Asia          5432.
## 5 Africa        2561.

Tratamento de dados em passos: operador Pipe (%>%) (cont.)

O operador pipe %>% faz o seguinte:

x %>% y(z) = y(x,z)

Ou seja, o primeiro operando é enfiado como primeiro parâmetro da função que está no segundo operando.

Isso faz com que possamos escrever o código anterior assim:

resultado <- gapminder %>% 
    filter(year == 2007) %>% 
    group_by(continent) %>% 
    summarise(
        media_gdp = sum(gdpPercap * pop) / sum(pop)
    ) %>% 
    arrange(desc(media_gdp))
    
resultado
## # A tibble: 5 x 2
##   continent media_gdp
##   <fct>         <dbl>
## 1 Oceania      32885.
## 2 Europe       25244.
## 3 Americas     21603.
## 4 Asia          5432.
## 5 Africa        2561.

Note que agora podemos interpretar o código facilmente como uma série de comandos de tratamento em cima dos dados.

Não é por coincidência que as funções de tratamento das bibliotecas tidyverse que veremos adiante são verbos e recebem os dados como primeiro parâmetro.

Agora o mais importante de tudo: O ATALHO PARA O %>% É CTRL + SHIFT + M

CRAN: uma Disneylândia dos dados?

CRAN é o repositório de bibliotecas mantido pelo R com contribuição de populares.

Além de funcionalidades estatísticas e funcionalidades para lidar com dados, há dados e funcionalidades para buscar dados online.

Usaremos várias das bases como exemplo.

A primeira é a do Banco Mundial, muito rica para quem gosta de dados socioeconômicos

Para acessar um indicador precisamos achá-lo na base de indicadores com a função wbsearch()

#pattern é uma expressão regular. \\ serve para dizer que "(" é mesmo "(" 
#e não o ( usado nas operações de expressão regular (fora do escopo do curso)
indicadores <- wbsearch(pattern = "GINI index \\(World Bank estimate\\)")

indicadores
##      indicatorID                        indicator
## 1348 SI.POV.GINI GINI index (World Bank estimate)

Sabendo o ID do indicador, podemos consultá-lo com a função wb()

#mrv é most recent values. Pode ser usado para buscar os n valores mais recentes
gini = wb(indicator = "SI.POV.GINI", mrv= 10, POSIXct = TRUE)

head(gini)
##     iso3c date value indicatorID                        indicator iso2c
## 486   ALB 2012  29.0 SI.POV.GINI GINI index (World Bank estimate)    AL
## 490   ALB 2008  30.0 SI.POV.GINI GINI index (World Bank estimate)    AL
## 497   DZA 2011  27.6 SI.POV.GINI GINI index (World Bank estimate)    DZ
## 530   AGO 2008  42.7 SI.POV.GINI GINI index (World Bank estimate)    AO
## 541   ARG 2017  40.6 SI.POV.GINI GINI index (World Bank estimate)    AR
## 542   ARG 2016  42.4 SI.POV.GINI GINI index (World Bank estimate)    AR
##       country    date_ct granularity
## 486   Albania 2012-01-01      annual
## 490   Albania 2008-01-01      annual
## 497   Algeria 2011-01-01      annual
## 530    Angola 2008-01-01      annual
## 541 Argentina 2017-01-01      annual
## 542 Argentina 2016-01-01      annual

Funções básicas de tratamento (dplyr): select()

dplyr é uma das bibliotecas que fqzem parte do conjunto tidyverse

A função select() é usada para selecionar colunas do dataframe/tibble

glimpse(gini)
## Observations: 684
## Variables: 9
## $ iso3c       <chr> "ALB", "ALB", "DZA", "AGO", "ARG", "ARG", "ARG", "...
## $ date        <chr> "2012", "2008", "2011", "2008", "2017", "2016", "2...
## $ value       <dbl> 29.0, 30.0, 27.6, 42.7, 40.6, 42.4, 41.4, 41.0, 41...
## $ indicatorID <chr> "SI.POV.GINI", "SI.POV.GINI", "SI.POV.GINI", "SI.P...
## $ indicator   <chr> "GINI index (World Bank estimate)", "GINI index (W...
## $ iso2c       <chr> "AL", "AL", "DZ", "AO", "AR", "AR", "AR", "AR", "A...
## $ country     <chr> "Albania", "Albania", "Algeria", "Angola", "Argent...
## $ date_ct     <date> 2012-01-01, 2008-01-01, 2011-01-01, 2008-01-01, 2...
## $ granularity <chr> "annual", "annual", "annual", "annual", "annual", ...
gini_select <- gini %>% 
    select(country, date, value, iso3c)

head(gini_select)
##       country date value iso3c
## 486   Albania 2012  29.0   ALB
## 490   Albania 2008  30.0   ALB
## 497   Algeria 2011  27.6   DZA
## 530    Angola 2008  42.7   AGO
## 541 Argentina 2017  40.6   ARG
## 542 Argentina 2016  42.4   ARG

É possível usar a seleção negativa assim como fizemos com vetores

gini_select2 <- gini_select %>% 
    select(-iso3c)

head(gini_select2)
##       country date value
## 486   Albania 2012  29.0
## 490   Albania 2008  30.0
## 497   Algeria 2011  27.6
## 530    Angola 2008  42.7
## 541 Argentina 2017  40.6
## 542 Argentina 2016  42.4

Funções básicas de tratamento (dplyr): select() (cont.)

Algumas funções helpers nos ajudam a usar a função select e são muito úteis para tratamentos mais elaborados.

Pra mostrar mais funcionalidades da função select, vamos usar uma base com dados eleitorais brasileiros, que retorna mais colunas

candidatos <- candidate_fed(2018)
## Processing the data...
## Done.
glimpse(candidatos)
## Observations: 29,113
## Variables: 58
## $ DATA_GERACAO                   <chr> "15/11/2018", "15/11/2018", "15...
## $ HORA_GERACAO                   <time> 20:03:47, 20:03:47, 20:03:47, ...
## $ ANO_ELEICAO                    <dbl> 2018, 2018, 2018, 2018, 2018, 2...
## $ COD_TIPO_ELEICAO               <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2...
## $ NOME_TIPO_ELEICAO              <chr> "ELEIÇÃO ORDINÁRIA", "ELEIÇÃO O...
## $ NUM_TURNO                      <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1...
## $ COD_ELEICAO                    <dbl> 297, 297, 297, 297, 297, 297, 2...
## $ DESCRICAO_ELEICAO              <chr> "Eleições Gerais Estaduais 2018...
## $ DATA_ELEICAO                   <chr> "07/10/2018", "07/10/2018", "07...
## $ ABRANGENCIA                    <chr> "ESTADUAL", "ESTADUAL", "ESTADU...
## $ SIGLA_UF                       <chr> "AC", "AC", "AC", "AC", "AC", "...
## $ SIGLA_UE                       <chr> "AC", "AC", "AC", "AC", "AC", "...
## $ DESCRICAO_UE                   <chr> "ACRE", "ACRE", "ACRE", "ACRE",...
## $ CODIGO_CARGO                   <dbl> 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7...
## $ DESCRICAO_CARGO                <chr> "DEPUTADO ESTADUAL", "DEPUTADO ...
## $ SEQUENCIAL_CANDIDATO           <dbl> 10000601020, 10000603904, 10000...
## $ NUMERO_CANDIDATO               <dbl> 14088, 31100, 45456, 35193, 173...
## $ NOME_CANDIDATO                 <chr> "ANA ISLA ARRUDA FREITAS", "MAR...
## $ NOME_URNA_CANDIDATO            <chr> "ANA FREITAS", "LORA DO COMERCI...
## $ NOME_SOCIAL_CANDIDATO          <chr> "#NULO#", "#NULO#", "#NULO#", "...
## $ CPF_CANDIDATO                  <chr> "93353405291", "63049112204", "...
## $ EMAIL_CANDIDATO                <chr> "ANAFREITAS.AIF@GMAIL.COM", "JU...
## $ COD_SITUACAO_CANDIDATURA       <dbl> 12, 12, 12, 12, 12, 12, 12, 12,...
## $ DES_SITUACAO_CANDIDATURA       <chr> "APTO", "APTO", "APTO", "APTO",...
## $ COD_DETALHE_SITUACAO_CAND      <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2...
## $ DES_DETALHE_SITUACAO_CAND      <chr> "DEFERIDO", "DEFERIDO", "DEFERI...
## $ TIPO_AGREMIACAO                <chr> "PARTIDO ISOLADO", "COLIGAÇÃO",...
## $ NUMERO_PARTIDO                 <dbl> 14, 31, 45, 35, 17, 27, 13, 13,...
## $ SIGLA_PARTIDO                  <chr> "PTB", "PHS", "PSDB", "PMB", "P...
## $ NOME_PARTIDO                   <chr> "PARTIDO TRABALHISTA BRASILEIRO...
## $ CODIGO_LEGENDA                 <dbl> 10000050036, 10000050109, 10000...
## $ NOME_COLIGACAO                 <chr> "PARTIDO ISOLADO", "FORÇA DA UN...
## $ COMPOSICAO_LEGENDA             <chr> "PTB", "PMB / PHS", "PSDB / DEM...
## $ CODIGO_NACIONALIDADE           <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1...
## $ DESCRICAO_NACIONALIDADE        <chr> "BRASILEIRA NATA", "BRASILEIRA ...
## $ SIGLA_UF_NASCIMENTO            <chr> "AC", "AC", "AC", "AC", "AC", "...
## $ CODIGO_MUNICIPIO_NASCIMENTO    <dbl> -3, -3, -3, -3, -3, -3, -3, -3,...
## $ NOME_MUNICIPIO_NASCIMENTO      <chr> "RIO BRANCO", "TARAUCÁ", "FEIJÓ...
## $ DATA_NASCIMENTO                <chr> "12/08/1987", "10/02/1976", "12...
## $ IDADE_DATA_POSSE               <dbl> 31, 42, 44, 47, 31, 26, 38, 39,...
## $ NUM_TITULO_ELEITORAL_CANDIDATO <chr> "005491592429", "001633372461",...
## $ CODIGO_SEXO                    <dbl> 4, 4, 4, 2, 2, 2, 2, 2, 2, 4, 2...
## $ DESCRICAO_SEXO                 <chr> "FEMININO", "FEMININO", "FEMINI...
## $ COD_GRAU_INSTRUCAO             <dbl> 4, 3, 6, 8, 7, 6, 8, 8, 7, 8, 8...
## $ DESCRICAO_GRAU_INSTRUCAO       <chr> "ENSINO FUNDAMENTAL COMPLETO", ...
## $ CODIGO_ESTADO_CIVIL            <dbl> 1, 1, 3, 3, 3, 1, 3, 3, 1, 3, 3...
## $ DESCRICAO_ESTADO_CIVIL         <chr> "SOLTEIRO(A)", "SOLTEIRO(A)", "...
## $ CODIGO_COR_RACA                <chr> "03", "01", "01", "03", "03", "...
## $ DESCRICAO_COR_RACA             <chr> "PARDA", "BRANCA", "BRANCA", "P...
## $ CODIGO_OCUPACAO                <dbl> 581, 169, 999, 297, 999, 999, 2...
## $ DESCRICAO_OCUPACAO             <chr> "DONA DE CASA", "COMERCIANTE", ...
## $ DESPESA_MAX_CAMPANHA           <dbl> 0, -1, 0, -1, 0, 0, 0, 0, -1, 0...
## $ COD_SIT_TOT_TURNO              <dbl> 5, 5, 5, 5, 5, 4, 3, 5, 5, 4, 2...
## $ DESC_SIT_TOT_TURNO             <chr> "SUPLENTE", "SUPLENTE", "SUPLEN...
## $ SITUACAO_REELEICAO             <chr> "N", "N", "N", "N", "N", "N", "...
## $ SITUACAO_DECLARAR_BENS         <chr> "N", "N", "S", "S", "N", "N", "...
## $ NUMERO_PROTOCOLO_CANDIDATURA   <dbl> -1, -1, -1, -1, -1, -1, -1, -1,...
## $ NUMERO_PROCESSO                <chr> "06002996220186010000", "060045...

Funções básicas de tratamento (dplyr): select() - helpers

candidatos_select <- candidatos %>% 
    select(starts_with("NOME"))

datatable(head(candidatos_select))
candidatos_select <- candidatos %>% 
    select(ends_with("candidato"))

datatable(head(candidatos_select))
candidatos_select <- candidatos %>% 
    select(contains("municipio"))

datatable(head(candidatos_select))
candidatos_select <- candidatos %>% 
    select(ends_with("candidato"))

datatable(head(candidatos_select))

Funções básicas de tratamento (dplyr): select() - helpers (cont.)

A função helper num_range ajuda a encontrar colunas do tipo prefixo_n. Isso é muito comum em bases de dados

A biblioteca worldmet retorna dados de estações meteorológicas espalhadas pelo planeta

Primeiro é necessário encontrar o código da base desejada

estacao <- getMeta("heathrow", returnMap = TRUE)

estacao

Funções básicas de tratamento (dplyr): select() - helpers (cont.)

A função abaixo retorna os dados de uma estação. Veja que alguns campos têm um sufixo _n

dados_heathrow <- importNOAA(code = "037720-99999", year = 2019,
precip = TRUE, PWC = FALSE, parallel = TRUE)


glimpse(dados_heathrow)
## Observations: 6,022
## Variables: 26
## $ date        <dttm> 2019-01-01 00:00:00, 2019-01-01 01:00:00, 2019-01...
## $ usaf        <chr> "037720", "037720", "037720", "037720", "037720", ...
## $ wban        <chr> "99999", "99999", "99999", "99999", "99999", "9999...
## $ code        <chr> "037720-99999", "037720-99999", "037720-99999", "0...
## $ station     <chr> "HEATHROW", "HEATHROW", "HEATHROW", "HEATHROW", "H...
## $ lat         <dbl> 51.47967, 51.47967, 51.47967, 51.47967, 51.47967, ...
## $ lon         <dbl> -0.4573333, -0.4573333, -0.4573333, -0.4573333, -0...
## $ elev        <dbl> 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25...
## $ wd          <dbl> 283.706052, 286.994553, 290.000000, 290.000000, 27...
## $ ws          <dbl> 3.266667, 3.433333, 4.100000, 3.433333, 3.266667, ...
## $ ceil_hgt    <dbl> 657.3333, 667.3333, 728.0000, 768.0000, 778.3333, ...
## $ visibility  <dbl> 22000, 28000, 45000, 45000, 35000, 35000, 28000, 2...
## $ air_temp    <dbl> 8.666667, 8.933333, 9.000000, 9.000000, 7.966667, ...
## $ dew_point   <dbl> 4.9333333, 4.9666667, 4.7666667, 4.8000000, 4.8000...
## $ atmos_pres  <dbl> 1034.8, 1034.5, 1034.6, 1034.5, 1034.4, 1033.9, 10...
## $ RH          <dbl> 77.67802, 76.42835, 75.06237, 75.23079, 80.81974, ...
## $ cl_1        <dbl> 7.666667, 8.000000, 7.666667, 8.000000, 7.666667, ...
## $ cl_1_height <dbl> 657.3333, 667.3333, 728.0000, 768.0000, 778.3333, ...
## $ cl_2        <dbl> 8.000000, NA, 8.000000, NA, NA, NA, 7.000000, 7.00...
## $ cl_2_height <dbl> 792, NA, 914, NA, NA, NA, 1006, 1036, NA, 720, 121...
## $ cl_3        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
## $ cl_3_height <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
## $ precip_12   <dbl> NA, NA, NA, NA, NA, NA, 0, NA, NA, NA, NA, NA, NA,...
## $ precip_6    <dbl> 0, NA, NA, NA, NA, NA, 0, NA, NA, NA, NA, NA, 0, N...
## $ cl          <dbl> 8.000000, 8.000000, 8.000000, 8.000000, 7.666667, ...
## $ precip      <dbl> NA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...

A função helper num_range ajuda a selecionar essas colunas com prefixo comum e um sufixo numérico

dados_heathrow_select <- dados_heathrow %>% 
    select( 
        date, 
        num_range("cl_", 1:3 ), 
        num_range("precip_", c(6, 12))  
    )


head(dados_heathrow_select)
## # A tibble: 6 x 6
##   date                 cl_1  cl_2  cl_3 precip_6 precip_12
##   <dttm>              <dbl> <dbl> <dbl>    <dbl>     <dbl>
## 1 2019-01-01 00:00:00  7.67     8    NA        0        NA
## 2 2019-01-01 01:00:00  8       NA    NA       NA        NA
## 3 2019-01-01 02:00:00  7.67     8    NA       NA        NA
## 4 2019-01-01 03:00:00  8       NA    NA       NA        NA
## 5 2019-01-01 04:00:00  7.67    NA    NA       NA        NA
## 6 2019-01-01 05:00:00  6       NA    NA       NA        NA

Outra função útil é a everything, que ajuda, por exemplo, a passar algumas colunas para o início do tibble.

dados_heathrow_select <- dados_heathrow %>% 
    select( 
        date, 
        air_temp,
        everything() 
    )


glimpse(dados_heathrow_select)
## Observations: 6,022
## Variables: 26
## $ date        <dttm> 2019-01-01 00:00:00, 2019-01-01 01:00:00, 2019-01...
## $ air_temp    <dbl> 8.666667, 8.933333, 9.000000, 9.000000, 7.966667, ...
## $ usaf        <chr> "037720", "037720", "037720", "037720", "037720", ...
## $ wban        <chr> "99999", "99999", "99999", "99999", "99999", "9999...
## $ code        <chr> "037720-99999", "037720-99999", "037720-99999", "0...
## $ station     <chr> "HEATHROW", "HEATHROW", "HEATHROW", "HEATHROW", "H...
## $ lat         <dbl> 51.47967, 51.47967, 51.47967, 51.47967, 51.47967, ...
## $ lon         <dbl> -0.4573333, -0.4573333, -0.4573333, -0.4573333, -0...
## $ elev        <dbl> 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25...
## $ wd          <dbl> 283.706052, 286.994553, 290.000000, 290.000000, 27...
## $ ws          <dbl> 3.266667, 3.433333, 4.100000, 3.433333, 3.266667, ...
## $ ceil_hgt    <dbl> 657.3333, 667.3333, 728.0000, 768.0000, 778.3333, ...
## $ visibility  <dbl> 22000, 28000, 45000, 45000, 35000, 35000, 28000, 2...
## $ dew_point   <dbl> 4.9333333, 4.9666667, 4.7666667, 4.8000000, 4.8000...
## $ atmos_pres  <dbl> 1034.8, 1034.5, 1034.6, 1034.5, 1034.4, 1033.9, 10...
## $ RH          <dbl> 77.67802, 76.42835, 75.06237, 75.23079, 80.81974, ...
## $ cl_1        <dbl> 7.666667, 8.000000, 7.666667, 8.000000, 7.666667, ...
## $ cl_1_height <dbl> 657.3333, 667.3333, 728.0000, 768.0000, 778.3333, ...
## $ cl_2        <dbl> 8.000000, NA, 8.000000, NA, NA, NA, 7.000000, 7.00...
## $ cl_2_height <dbl> 792, NA, 914, NA, NA, NA, 1006, 1036, NA, 720, 121...
## $ cl_3        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
## $ cl_3_height <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
## $ precip_12   <dbl> NA, NA, NA, NA, NA, NA, 0, NA, NA, NA, NA, NA, NA,...
## $ precip_6    <dbl> 0, NA, NA, NA, NA, NA, 0, NA, NA, NA, NA, NA, 0, N...
## $ cl          <dbl> 8.000000, 8.000000, 8.000000, 8.000000, 7.666667, ...
## $ precip      <dbl> NA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...

Funções básicas de tratamento (dplyr) arrange():

A função arrange serve para ordenar o tibble.

dados_ordenados <- dados_heathrow %>% 
    arrange(date)

head(dados_ordenados)
## # A tibble: 6 x 26
##   date                usaf  wban  code  station   lat    lon  elev    wd
##   <dttm>              <chr> <chr> <chr> <chr>   <dbl>  <dbl> <dbl> <dbl>
## 1 2019-01-01 00:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25  284.
## 2 2019-01-01 01:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25  287.
## 3 2019-01-01 02:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25  290 
## 4 2019-01-01 03:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25  290 
## 5 2019-01-01 04:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25  276.
## 6 2019-01-01 05:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25  267.
## # ... with 17 more variables: ws <dbl>, ceil_hgt <dbl>, visibility <dbl>,
## #   air_temp <dbl>, dew_point <dbl>, atmos_pres <dbl>, RH <dbl>,
## #   cl_1 <dbl>, cl_1_height <dbl>, cl_2 <dbl>, cl_2_height <dbl>,
## #   cl_3 <dbl>, cl_3_height <dbl>, precip_12 <dbl>, precip_6 <dbl>,
## #   cl <dbl>, precip <dbl>

A função desc() permite a ordenação decrescente

dados_ordenados <- dados_heathrow %>% 
    arrange(desc(date))

head(dados_ordenados)
## # A tibble: 6 x 26
##   date                usaf  wban  code  station   lat    lon  elev     wd
##   <dttm>              <chr> <chr> <chr> <chr>   <dbl>  <dbl> <dbl>  <dbl>
## 1 2019-09-08 21:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.456    25 168.  
## 2 2019-09-08 20:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25 143.  
## 3 2019-09-08 19:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25  53.3 
## 4 2019-09-08 18:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25 353.  
## 5 2019-09-08 17:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25 320   
## 6 2019-09-08 16:00:00 0377~ 99999 0377~ HEATHR~  51.5 -0.457    25   5.53
## # ... with 17 more variables: ws <dbl>, ceil_hgt <dbl>, visibility <dbl>,
## #   air_temp <dbl>, dew_point <dbl>, atmos_pres <dbl>, RH <dbl>,
## #   cl_1 <dbl>, cl_1_height <dbl>, cl_2 <dbl>, cl_2_height <dbl>,
## #   cl_3 <dbl>, cl_3_height <dbl>, precip_12 <dbl>, precip_6 <dbl>,
## #   cl <dbl>, precip <dbl>

Funções básicas de tratamento (dplyr) group_by():

A função group_by será bastante usada..

Quem conhece SQL pode estranhar um pouco o comportamento desta função, pois ela não agrupa os dados diminuindo o número de linhas imediatamente.

gini_agrupado <- gini %>% 
    select(country, date, value) %>% 
    group_by(country) 
    
gini_agrupado
## # A tibble: 684 x 3
## # Groups:   country [152]
##    country   date  value
##  * <chr>     <chr> <dbl>
##  1 Albania   2012   29  
##  2 Albania   2008   30  
##  3 Algeria   2011   27.6
##  4 Angola    2008   42.7
##  5 Argentina 2017   40.6
##  6 Argentina 2016   42.4
##  7 Argentina 2014   41.4
##  8 Argentina 2013   41  
##  9 Argentina 2012   41.2
## 10 Argentina 2011   42.3
## # ... with 674 more rows

Leitura de dados

-read_csv

-read_fwf

-read_excel

Funções de junção (dplyr)

Funções de pivot (tidyr)

Funções de pivot (tidyselect)

manobras com vars, starts_with, num_range etc

Tratamento de strings (caracteres) com stringr

Tratamento de datas (lubridate)

Tratamento de dados categóricos (forcats)

VISUALIZAÇÃO DE DADOS

PROGRAMAÇÃO FUNCIONAL

Simulação CFA com vários parâmetros

n_simul <- 10000
n_questoes <- 240
min_aprovacao <-  0.6
n_aprovado <- 240 * min_aprovacao
prob_questao <- 0.2


estimar_chance <-  function(...){
    
    print("aqui")
    fracao_eliminar_questoes <- as.vector(...)
    
    #definindo o número de questões 
    n_questoes_cada_elimina <- t(rmultinom(n_simul, size = n_questoes, fracao_eliminar_questoes))
    probs_quando_elimina <- 1/(5:1)
    acertos_concatenados <- 
        rbinom( 
            n =  n_simul * 5 , 
            size = as.vector(t(n_questoes_cada_elimina)), 
            prob = probs_quando_elimina  
        )
    
    matriz_acertos <- matrix(acertos_concatenados, byrow = TRUE, nrow = n_simul )
    
    acertos <- rowSums(matriz_acertos)
    sum(acertos > n_aprovado)/n_simul
}


#definindo a chance podermos eliminar 0, 1, 2, ... 4 alternativas
resultados <- RandVec(n = 5, m = 100) %>% 
    .$RandVecOutput %>% 
    t() %>% 
    as_tibble() %>% 
    mutate(id = row_number()) %>% 
    group_by(id) %>% 
    nest() %>% 
    mutate(data_fica = data) %>%     
    mutate(data = map(data, estimar_chance) ) %>% 
    unnest()
## Warning: `as_tibble.matrix()` requires a matrix with column names or a `.name_repair` argument. Using compatibility `.name_repair`.
## This warning is displayed once per session.
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"
## [1] "aqui"

Aplicação de funções a dataframes (purrr)

map-reduce

EXECUTANDO MODELOS

Execução de modelos com broom

Execução de modelos com caret

SÉRIES TEMPORAIS

Repositórios de séries temporais

Manipulação de séries temporais

Biblioteca Forecast

COMUNICANDO OS RESULTADOS

Criando relatórios com R Markdown

Livros

Referência Bookdown

Criando visualizações interativas com Shiny